@ecency/render-helper 2.5.0 → 2.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -54,13 +54,13 @@ var SECTION_LIST = [
54
54
  // src/consts/regexes.const.ts
55
55
  var IMG_REGEX = /(https?:\/\/.*\.(?:tiff?|jpe?g|gif|png|svg|ico|heic|webp|arw))(.*)/gim;
56
56
  var IPFS_REGEX = /^https?:\/\/[^/]+\/(ip[fn]s)\/([^/?#]+)/gim;
57
- var POST_REGEX = /^https?:\/\/(.*)\/(.*)\/(@[\w.\d-]+)\/(.*)/i;
57
+ var POST_REGEX = /^https?:\/\/([^/]+)\/([^/]+)\/(@[\w.\d-]+)\/(.+)$/i;
58
58
  var CCC_REGEX = /^https?:\/\/(.*)\/ccc\/([\w.\d-]+)\/(.*)/i;
59
59
  var MENTION_REGEX = /^https?:\/\/(.*)\/(@[\w.\d-]+)$/i;
60
60
  var TOPIC_REGEX = /^https?:\/\/(.*)\/(trending|hot|created|promoted|muted|payout)\/(.*)$/i;
61
61
  var INTERNAL_MENTION_REGEX = /^\/@[\w.\d-]+$/i;
62
62
  var INTERNAL_TOPIC_REGEX = /^\/(trending|hot|created|promoted|muted|payout)\/(.*)$/i;
63
- var INTERNAL_POST_TAG_REGEX = /(.*)\/(@[\w.\d-]+)\/(.*)/i;
63
+ var INTERNAL_POST_TAG_REGEX = /^(.+?)\/(@[\w.\d-]+)\/(.*)$/i;
64
64
  var INTERNAL_POST_REGEX = /^\/(@[\w.\d-]+)\/(.*)$/i;
65
65
  var CUSTOM_COMMUNITY_REGEX = /^https?:\/\/(.*)\/c\/(hive-\d+)(.*)/i;
66
66
  var YOUTUBE_REGEX = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|shorts\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i;
@@ -298,6 +298,81 @@ function createDoc(html) {
298
298
  function makeEntryCacheKey(entry) {
299
299
  return `${entry.author}-${entry.permlink}-${entry.last_update}-${entry.updated}`;
300
300
  }
301
+ function stripHtmlTags(s) {
302
+ const n = s.length;
303
+ let out = "";
304
+ let i = 0;
305
+ while (i < n) {
306
+ const lt = s.indexOf("<", i);
307
+ if (lt < 0) {
308
+ out += s.slice(i);
309
+ break;
310
+ }
311
+ out += s.slice(i, lt);
312
+ const gt = s.indexOf(">", lt + 1);
313
+ if (gt < 0) {
314
+ out += s.slice(lt);
315
+ break;
316
+ }
317
+ if (gt === lt + 1) {
318
+ out += s.slice(lt, gt + 1);
319
+ i = gt + 1;
320
+ continue;
321
+ }
322
+ i = gt + 1;
323
+ }
324
+ return out;
325
+ }
326
+ function trimTrailingSlash(s) {
327
+ let end = s.length;
328
+ while (end > 0 && s.charCodeAt(end - 1) === 47) end--;
329
+ return s.slice(0, end);
330
+ }
331
+ function stripQueryString(s) {
332
+ const q = s.indexOf("?");
333
+ return q >= 0 && q < s.length - 1 ? s.slice(0, q) : s;
334
+ }
335
+ function isHtmlWhitespace(c) {
336
+ return c === 32 || c === 9 || c === 10 || c === 13 || c === 12;
337
+ }
338
+ function moveBlockClosingTagOutOfParagraph(html, blockTags) {
339
+ const n = html.length;
340
+ let out = "";
341
+ let i = 0;
342
+ while (i < n) {
343
+ const pStart = html.indexOf("</p>", i);
344
+ if (pStart < 0) {
345
+ out += html.slice(i);
346
+ break;
347
+ }
348
+ if (pStart === i || html.charCodeAt(pStart - 1) !== 62) {
349
+ out += html.slice(i, pStart + 4);
350
+ i = pStart + 4;
351
+ continue;
352
+ }
353
+ const closingStart = html.lastIndexOf("</", pStart - 2);
354
+ if (closingStart < i) {
355
+ out += html.slice(i, pStart + 4);
356
+ i = pStart + 4;
357
+ continue;
358
+ }
359
+ const tagName = html.slice(closingStart + 2, pStart - 1).toLowerCase();
360
+ if (!blockTags.has(tagName)) {
361
+ out += html.slice(i, pStart + 4);
362
+ i = pStart + 4;
363
+ continue;
364
+ }
365
+ let k = closingStart;
366
+ while (k > i && isHtmlWhitespace(html.charCodeAt(k - 1))) k--;
367
+ if (k - 4 >= i && html.slice(k - 4, k).toLowerCase() === "<br>") {
368
+ k -= 4;
369
+ while (k > i && isHtmlWhitespace(html.charCodeAt(k - 1))) k--;
370
+ }
371
+ out += html.slice(i, k) + "</p>" + html.slice(closingStart, pStart);
372
+ i = pStart + 4;
373
+ }
374
+ return out;
375
+ }
301
376
  function extractYtStartTime(url) {
302
377
  try {
303
378
  const urlObj = new URL(url);
@@ -384,7 +459,7 @@ function sanitizeHtml(html) {
384
459
  }
385
460
  });
386
461
  }
387
- var proxyBase = "https://images.ecency.com";
462
+ var proxyBase = "https://i.ecency.com";
388
463
  var urlHashCache = new LRUCache({ max: 500 });
389
464
  function getUrlHash(url) {
390
465
  const cached = urlHashCache.get(url);
@@ -427,6 +502,9 @@ function proxifyImageSrc(url, width = 0, height = 0, _format = "match") {
427
502
  if (url.indexOf("https://steemitimages.com/") === 0 && url.indexOf("https://steemitimages.com/D") !== 0) {
428
503
  return url.replace("https://steemitimages.com", proxyBase);
429
504
  }
505
+ if (url.indexOf("https://images.ecency.com/") === 0) {
506
+ return url.replace("https://images.ecency.com", proxyBase);
507
+ }
430
508
  const realUrl = getLatestUrl(url);
431
509
  const pHash = extractPHash(realUrl);
432
510
  const options = {
@@ -496,7 +574,7 @@ function img(el, state) {
496
574
  }
497
575
  const cls = el.getAttribute("class") || "";
498
576
  const shouldReplace = !cls.includes("no-replace");
499
- const base = getProxyBase().replace(/\/+$/, "");
577
+ const base = trimTrailingSlash(getProxyBase());
500
578
  const hasAlreadyProxied = src.startsWith(`${base}/p/`) || src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
501
579
  if (shouldReplace && !hasAlreadyProxied) {
502
580
  const proxified = proxifyImageSrc(decodedSrc);
@@ -521,7 +599,7 @@ function img(el, state) {
521
599
  function createImageHTML(src, isLCP) {
522
600
  const proxified = proxifyImageSrc(src);
523
601
  if (!proxified) return "";
524
- const base = getProxyBase().replace(/\/+$/, "");
602
+ const base = trimTrailingSlash(getProxyBase());
525
603
  const isAlreadyProxied = src.startsWith(`${base}/u/`) || new RegExp(`^${base.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}/\\d+x\\d+/`).test(src);
526
604
  const srcset = isAlreadyProxied ? "" : buildSrcSet(src);
527
605
  const loading = isLCP ? "eager" : "lazy";
@@ -555,7 +633,8 @@ var matchesHref = (href, value) => {
555
633
  return normalizeValue(value) === normalizedHref;
556
634
  };
557
635
  var normalizeDisplayText = (text2) => {
558
- return text2.trim().replace(/^https?:\/\/(www\.)?(ecency\.com|peakd\.com|hive\.blog)/i, "").replace(/^\/+/, "").split("?")[0].replace(/#@.*$/i, "").replace(/\/+$/, "").toLowerCase();
636
+ const beforeTrailingSlash = text2.trim().replace(/^https?:\/\/(www\.)?(ecency\.com|peakd\.com|hive\.blog)/i, "").replace(/^\/+/, "").split("?")[0].replace(/#@.*$/i, "");
637
+ return trimTrailingSlash(beforeTrailingSlash).toLowerCase();
559
638
  };
560
639
  var getInlineMeta = (el, href, author, permlink, communityTag) => {
561
640
  const textMatches = matchesHref(href, el.textContent);
@@ -1124,8 +1203,8 @@ function a(el, forApp, parentDomain = "ecency.com", seoContext, renderOptions) {
1124
1203
  TWITTER_REGEX.lastIndex = 0;
1125
1204
  const e = TWITTER_REGEX.exec(href);
1126
1205
  if (e) {
1127
- const url = e[0].replace(/(<([^>]+)>)/gi, "");
1128
- const author = e[1].replace(/(<([^>]+)>)/gi, "");
1206
+ const url = stripHtmlTags(e[0]);
1207
+ const author = stripHtmlTags(e[1]);
1129
1208
  const blockquote = el.ownerDocument.createElement("blockquote");
1130
1209
  blockquote.setAttribute("class", "twitter-tweet");
1131
1210
  const p2 = el.ownerDocument.createElement("p");
@@ -1201,8 +1280,7 @@ function iframe(el, parentDomain = "ecency.com", forApp = false) {
1201
1280
  return;
1202
1281
  }
1203
1282
  if (src.match(YOUTUBE_EMBED_REGEX)) {
1204
- const s = src.replace(/\?.+$/, "");
1205
- el.setAttribute("src", s);
1283
+ el.setAttribute("src", stripQueryString(src));
1206
1284
  return;
1207
1285
  }
1208
1286
  if (src.match(BITCHUTE_REGEX)) {
@@ -1383,7 +1461,7 @@ function linkify(content, forApp, renderOptions) {
1383
1461
  const preceedings = (preceeding1 || "") + (preceeding2 || "");
1384
1462
  if (userLower.indexOf("/") === -1 && isValidUsername(user)) {
1385
1463
  if (!forApp) {
1386
- const avatarSrc = `https://images.ecency.com/u/${userLower}/avatar/small`;
1464
+ const avatarSrc = `${getProxyBase()}/u/${userLower}/avatar/small`;
1387
1465
  const html = `${preceedings}<a class="er-author er-author-link" href="/@${userLower}"><img class="er-author-link-image" src="${avatarSrc}" alt="${userLower}"/><span class="er-author-link-content"><span class="er-author-link-label">Hive account</span><span>@${userLower}</span></span></a>`;
1388
1466
  const placeholder = `\u200C${authorPlaceholders.length}\u200C`;
1389
1467
  authorPlaceholders.push({ placeholder, html });
@@ -1597,16 +1675,16 @@ if (typeof window === "undefined") {
1597
1675
  loadLolight().catch(() => {
1598
1676
  });
1599
1677
  }
1678
+ var BLOCK_TAGS_ALTERNATION = "center|div|table|figure|section|article|aside|header|footer|nav|main";
1679
+ var BLOCK_TAGS_SET = new Set(BLOCK_TAGS_ALTERNATION.split("|"));
1600
1680
  function fixBlockLevelTagsInParagraphs(html) {
1601
- const blockTags = "center|div|table|figure|section|article|aside|header|footer|nav|main";
1602
- const openingPattern = new RegExp(`<p>(<(?:${blockTags})(?:\\s[^>]*)?>)<\\/p>`, "gi");
1681
+ const openingPattern = new RegExp(`<p>(<(?:${BLOCK_TAGS_ALTERNATION})(?:\\s[^>]*)?>)<\\/p>`, "gi");
1603
1682
  html = html.replace(openingPattern, "$1");
1604
- const closingPattern = new RegExp(`<p>(<\\/(?:${blockTags})>)<\\/p>`, "gi");
1683
+ const closingPattern = new RegExp(`<p>(<\\/(?:${BLOCK_TAGS_ALTERNATION})>)<\\/p>`, "gi");
1605
1684
  html = html.replace(closingPattern, "$1");
1606
- const startPattern = new RegExp(`<p>(<(?:${blockTags})(?:\\s[^>]*)?>)(?:<br>)?\\s*`, "gi");
1685
+ const startPattern = new RegExp(`<p>(<(?:${BLOCK_TAGS_ALTERNATION})(?:\\s[^>]*)?>)(?:<br>)?\\s*`, "gi");
1607
1686
  html = html.replace(startPattern, "$1<p>");
1608
- const endPattern = new RegExp(`\\s*(?:<br>)?\\s*(<\\/(?:${blockTags})>)<\\/p>`, "gi");
1609
- html = html.replace(endPattern, "</p>$1");
1687
+ html = moveBlockClosingTagOutOfParagraph(html, BLOCK_TAGS_SET);
1610
1688
  html = html.replace(/<p>\s*<\/p>/g, "");
1611
1689
  html = html.replace(/<p><br>\s*<\/p>/g, "");
1612
1690
  return html;
@@ -1945,7 +2023,7 @@ function postBodySummary(entryBody, length = 200, platform = "web") {
1945
2023
  text2 = text2.split(placeholder).join(entity);
1946
2024
  });
1947
2025
  }
1948
- text2 = text2.replace(/(<([^>]+)>)/gi, "").replace(/\r?\n|\r/g, " ").replace(/(?:https?|ftp):\/\/[\n\S]+/g, "").trim().replace(/ +(?= )/g, "");
2026
+ text2 = stripHtmlTags(text2).replace(/\r?\n|\r/g, " ").replace(/(?:https?|ftp):\/\/[\n\S]+/g, "").trim().replace(/ {2,}/g, " ");
1949
2027
  if (length > 0) {
1950
2028
  text2 = joint(text2.split(" "), length);
1951
2029
  }